﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;

namespace Xejen.Communication.Endpoints
{
    /// <summary>
    /// 表示一个地址
    /// </summary>
    /// <typeparam name="T">实际地址</typeparam>
    /// <creator>marc</creator>
    public class Address<T>
    {
        private T _value;

        /// <summary>
        /// 实际地址
        /// <para>
        /// 若遇到死循环反序列化这个Value的情况，请改用System.Text.Json.JsonSerializer.Serialize(object);进行序列化
        /// </para>
        /// </summary>
        public T Value
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
                HasValue = true;
            }
        }

        /// <summary>
        /// 地址是否有值
        /// </summary>
        public bool HasValue { get; private set; }

        /// <inheritdoc cref="Address{T}"/>
        public Address() { }

        /// <inheritdoc cref="Address{T}"/>
        /// <param name="value"><inheritdoc cref="Value" path="/summary"/></param>
        public Address(T value)
        {
            _value = value;
            HasValue = true;
        }

        /// <summary>
        /// 从类型 T 到 Address{T} 的隐式转换
        /// </summary>
        /// <param name="value"></param>
        public static implicit operator Address<T>(T value)
        {
            return new Address<T>(value);
        }

        /// <summary>
        /// 从 Address{T} 到 T 的隐式转换
        /// </summary>
        /// <param name="address"></param>
        public static implicit operator T(Address<T> address)
        {
            return address.Value;
        }

        /// <inheritdoc/>
        public override string ToString()
        {
            return Value.ToString();
        }

        /// <inheritdoc/>
        public override int GetHashCode()
        {
            return Value.GetHashCode();
        }

        /// <inheritdoc/>
        public override bool Equals(object obj)
        {
            if (obj is T t)
            {
                return Value.Equals(t);
            }
            else if (obj is Address<T> address)
            {
                return Value.Equals(address.Value);
            }

            return false;

            //return Value.Equals((obj as Address<T>).Value);
        }
    }
}
